package service

import (
	"context"
	"errors"
	"log"
	"ollama-go/dto"
	"ollama-go/entity"
	"ollama-go/query"
	"ollama-go/toolkit"
	"ollama-go/vo"
	"strings"

	"github.com/androidsr/sc-go/model"
	"github.com/androidsr/sc-go/sbuilder"
	"github.com/androidsr/sc-go/sc"
	"github.com/androidsr/sc-go/sgorm"
	"github.com/tmc/langchaingo/schema"
)

var (
	ollamaEmbeddingService *OllamaEmbeddingService
)

type OllamaEmbeddingService struct {
	collectionService *OllamaCollectionService
}

func NewOllamaEmbeddingService() *OllamaEmbeddingService {
	if ollamaEmbeddingService == nil {
		ollamaEmbeddingService = new(OllamaEmbeddingService)
		ollamaEmbeddingService.collectionService = NewOllamaCollectionService()
	}
	return ollamaEmbeddingService
}

// 使用id获取数据
func (m OllamaEmbeddingService) Get(id string) *vo.OllamaEmbeddingVO {
	data := new(entity.OllamaEmbedding)
	data.Uuid = id
	err := sgorm.DB.GetOne(data)
	if err != nil {
		return nil
	}
	return sc.Copy[vo.OllamaEmbeddingVO](data)
}

// 保存数据
func (m OllamaEmbeddingService) Save(dto *dto.OllamaEmbeddingDTO) error {
	collection := NewOllamaCollectionService().Get(dto.CollectionId)
	if collection == nil {
		return errors.New("集合不存在")
	}
	dto.Metadata["filename"] = dto.Filename
	dto.Metadata["tenantId"] = dto.TenantId
	dto.Metadata["funcId"] = dto.FuncId
	err := toolkit.PG.SetStore(context.Background(), collection.Name).AddDocument(context.Background(), []schema.Document{{
		PageContent: dto.Document,
		Metadata:    dto.Metadata,
	}})
	if err != nil {
		log.Printf("保存向量数据出错：%v\n", err)
		return err
	}
	return err
}

// 更新数据
func (m OllamaEmbeddingService) UpdateById(dto *dto.OllamaEmbeddingDTO) error {
	collection := NewOllamaCollectionService().Get(dto.CollectionId)
	if collection == nil {
		return errors.New("集合不存在")
	}
	err := m.DeleteById(dto.Uuid)
	if err != nil {
		return errors.New("更新失败")
	}
	err = m.Save(dto)
	return err
}

// 删除数据
func (m OllamaEmbeddingService) DeleteById(id string) error {
	return sgorm.DB.DeleteById(entity.OllamaEmbedding{}, "uuid = ?", id)
}

// 分页列表查询
func (m OllamaEmbeddingService) QueryPage(query *query.OllamaEmbeddingQueryDTO) *model.PageResult {
	sql := `select b.name as collection_name,a.uuid, a.collection_id,a.document,
	a.cmetadata as metadata, a.cmetadata ->> 'funcId' as func_id,
	a.cmetadata ->> 'filename' as filename, a.cmetadata ->> 'tenantId' as tenant_id  
	from ollama_embedding a 
	left join ollama_collection b on a.collection_id = b.uuid where 1=1 `
	data := make([]vo.OllamaEmbeddingVO, 0)
	tenantId := query.TenantId
	query.TenantId = ""
	b := sbuilder.StructToBuilder(query, sql)
	b.Multiple().Ands(b.Eq("a.cmetadata ->> 'tenantId'", tenantId), b.Or().IsNull("a.cmetadata ->> 'tenantId'"))
	b.Append(" order by a.cmetadata ->> 'filename' desc")
	sql, values := b.Build()
	return sgorm.DB.SelectPage(&data, query.BaseQueryDTO.Page, sql, values...)
}

// 分页下拉查询
func (m OllamaEmbeddingService) QueryList(query *model.SelectQueryDTO) *model.PageResult {
	sql := `select distinct a.cmetadata ->> 'filename' as value, concat(b.name,' / ',a.cmetadata ->> 'filename') as label from ollama_embedding a left join ollama_collection b on a.collection_id = b.uuid where 1=1 `
	data := make([]model.SelectVO, 0)
	b := sbuilder.Builder(sql)
	b.Like("a.cmetadata ->> 'filename'", query.Label)
	for k, v := range query.Vars {
		b.Eq(k, v)
	}
	sql, values := b.Build()
	return sgorm.DB.SelectPage(&data, &query.Page, sql, values...)
}

func (m *OllamaEmbeddingService) DeleteByFilename(collectionId, filename string) error {
	err := sgorm.DB.Delete(entity.OllamaEmbedding{}, "collection_id = ? and cmetadata ->> 'filename' = ?", collectionId, filename).Error
	return err
}

func (m *OllamaEmbeddingService) DeleteByCollectionId(collectionId string) error {
	err := sgorm.DB.Delete(entity.OllamaEmbedding{}, "collection_id = ? ", collectionId).Error
	return err
}
func (m *OllamaEmbeddingService) DeleteMetaData(params map[string]interface{}) error {
	wheres := make([]string, 0)
	values := make([]interface{}, 0)
	for k, v := range params {
		if v == "" {
			continue
		}
		wheres = append(wheres, k+" = ?")
		values = append(values, v)
	}
	err := sgorm.DB.Delete(entity.OllamaEmbedding{}, strings.Join(wheres, " and "), values...).Error
	return err
}
